/**
 * Copyright (C) 2013-2014 the original author or authors.
 */
package com.foreveross.bsl.common.utils.web;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.foreveross.bsl.common.utils.mapper.JsonMapper;
import com.foreveross.bsl.common.utils.web.QueryOrder.Direction;

/**
 * xxx
 * 
 * @author Wangyi
 * @version v1.0
 * 
 * @date 2013-9-11
 * 
 */
public class QuerySpecs {

	public static final QuerySpecs EMPTY_QUERY_SPECS = new QuerySpecs();

	private final Collection<QueryFilter> filters;
	private final List<QueryOrder> orders;

	/**
	 * 
	 */
	public QuerySpecs() {
		filters = new HashSet<QueryFilter>();
		orders = new ArrayList<QueryOrder>();
	}

	public QuerySpecs(Collection<QueryFilter> filters) {
		this();
		if (filters != null) {
			this.filters.addAll(filters);
		}
	}

	/**
	 * params中的key为特殊约定的过虑格式：OPERATOR_FIELDNAME, eg: EQ_name，表示name等于;
	 * params中的value则是条件的具体值
	 * 
	 * @param params
	 */
	public void setFiltersByParamsMap(Map<String, Object> params) {
		this.filters.addAll(QueryFilter.parseToFilters(params));
	}

	/**
	 * params为排序属性的名值对，eg: name=DESC
	 * 
	 * @param params
	 */
	public void setOrdersByParamsMap(Map<String, Object> params) {
		for (Map.Entry<String, Object> entry : params.entrySet()) {
			this.orders.add(new QueryOrder(QueryOrder.Direction.valueOf(entry.getValue().toString()), entry.getKey()));
		}
	}

	/**
	 * @return the filters
	 */
	public Collection<QueryFilter> getFilters() {
		return Collections.unmodifiableCollection(filters);
	}

	@JsonIgnore
	public QueryFilter getFirstFilter() {
		if (!this.filters.isEmpty()) {
			return this.filters.iterator().next();
		}
		return QueryFilter.EMPTY_FILTER;
	}

	@JsonIgnore
	public QueryFilter getFilter(String fieldName) {
		for (QueryFilter qf : this.filters) {
			if (qf.getFieldName().equals(fieldName)) {
				return qf;
			}
		}
		return null;
	}

	/**
	 * @param filters
	 *            the filters to set
	 */
	public void setFilters(Collection<QueryFilter> filters) {
		this.filters.clear();
		this.filters.addAll(filters);
	}

	public List<QueryOrder> getOrders() {
		return Collections.unmodifiableList(this.orders);
	}

	public QuerySpecs addFilter(QueryFilter filter) {
		this.filters.add(filter);
		return this;
	}

	public QuerySpecs removeFilter(QueryFilter filter) {
		this.filters.remove(filter);
		return this;
	}

	public QuerySpecs replaceFilter(QueryFilter oldFilter, QueryFilter newFilter) {
		this.filters.remove(oldFilter);
		this.filters.add(newFilter);
		return this;
	}

	public QuerySpecs clearFilters() {
		this.filters.clear();
		return this;
	}

	public void setOrders(List<QueryOrder> orders) {
		this.orders.clear();
		this.orders.addAll(orders);
	}

	public QuerySpecs setOrder(String property, Direction direction) {
		this.removeOrder(property);
		this.orders.add(new QueryOrder(direction, property));
		return this;
	}

	public QueryOrder getOrder(String property) {
		return findQueryOrder(property);
	}

	public QuerySpecs removeOrder(String property) {
		QueryOrder qo = this.findQueryOrder(property);
		if (qo != null) {
			this.orders.remove(qo);
		}
		return this;
	}

	public QuerySpecs clearOrders() {
		this.orders.clear();
		return this;
	}

	private QueryOrder findQueryOrder(String property) {
		for (QueryOrder qo : this.orders) {
			if (qo.getProperty().equals(property)) {
				return qo;
			}
		}
		return null;
	}

	private static final JsonMapper jsonMapper = JsonMapper.nonEmptyMapper();

	/**
	 * 用于CXF在反序列化,value为QuerySpecs对象序列化的JSON字符串
	 * 
	 * @param value
	 * @return
	 */
	public static QuerySpecs valueOf(String value) {
		QuerySpecs sfs = jsonMapper.fromJson(value, QuerySpecs.class);
		return sfs;
	}

}
